package com.cy.pj.sys.common.aspect;

import com.cy.pj.common.anno.RequiredLog;
import com.cy.pj.sys.common.util.IPUtils;
import com.cy.pj.sys.common.util.ShiroUtils;
import com.cy.pj.sys.dao.SysUserDao;
import com.cy.pj.sys.pojo.SysLog;
import com.cy.pj.sys.pojo.SysUser;
import com.cy.pj.sys.service.SysLogService;
import com.cy.pj.sys.service.SysUserService;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;

/**
 * @author 张琪
 * @date 2020/11/20
 * @describe
 */

@Aspect
@Component
//@Slf4j
public class SysLogAspect2 {


    @Autowired
    private SysLogService sysLogService;


    @Pointcut("@annotation(com.cy.pj.common.anno.RequiredLog)")
    public void doLog(){}



    @Around("doLog()")
    public Object doAround(ProceedingJoinPoint joinPoint) throws Throwable {
        long t1 = System.currentTimeMillis();
        System.out.println(111);
        Object result = joinPoint.proceed();
        long t2 = System.currentTimeMillis();

        doSaveLog(joinPoint, t2 - t1);

        return result;
    }

    /**
     * 记录用户正常行为日志:
     * username (登陆用户)
     * ip       通过工具类获取
     * operation   通过连接点方法获取
     * method       通过连接点方法获取
     * params       通过连接点方法获取
     * time         执行方法时的耗时
     * createdTime  now()  日志的记录时间
     */
    private void doSaveLog(ProceedingJoinPoint joinPoint, long time) throws NoSuchMethodException, JsonProcessingException {
//        1. 获取用户行为日志
        String ip = IPUtils.getIpAddr();
        /* 获取目标方的法对象类型, 基于此类型获取目标方法*/
        Class<?> targetClass = joinPoint.getTarget().getClass();
        /* 获取方法签名, 存储了方法信息的一个对象*/
        MethodSignature ms = (MethodSignature)joinPoint.getSignature();
        /* 获取目标方法*/
        Method targetMethod =
                targetClass.getDeclaredMethod(ms.getName(), ms.getParameterTypes());
        RequiredLog requiredLog = targetMethod.getAnnotation(RequiredLog.class);
        System.err.println(targetClass.getAnnotation(RequiredLog.class));
        System.err.println(targetClass);
//        String methodName = targetClass.getName();
        String operation = requiredLog.operation();        //操作名
        String method = targetClass.getName() + "." + targetMethod.getName();           //目标方法
        String params = new ObjectMapper().writeValueAsString(joinPoint.getArgs());           //执行方法时传入的实际参数

//        2. 封装用户行为日志
        SysLog sysLog = new SysLog();
        SysUser sysUser = ShiroUtils.getUser();
        sysLog.setUsername(sysUser.getUsername());
        sysLog.setIp(ip);
        sysLog.setMethod(method);
        sysLog.setOperation(operation);
        sysLog.setParams(params);
        sysLog.setTime(time);
//        3. 保存用户行为日志
        int rows = sysLogService.saveObject(sysLog);

    }
}
